Fix ICE when data section exceeds 2^12 words#7643
Conversation
LW/LB instructions have 12-bit immediate offsets (max 4095). When copy-type loads exceeded this, realize_load() panicked. Replace the panic with a three-tier approach: <=12-bit uses single LW/LB, >12-bit uses MOVI+ADD+LW/LB (3 instructions), >18-bit panics with a clear message. Update op_size_in_bytes and instruction_size_not_far_jump to return matching instruction counts so jump offsets remain correct.
Exercises the >12-bit offset path by creating 4200+ distinct u64 data section entries (values >262143 to avoid MOVI inlining). Verifies correct codegen via checksum of all loaded values.
|
Thanks for the contribution! Before we can merge this, we need @Dnreikronos to sign the Fuel Labs Contributor License Agreement. |
PR SummaryMedium Risk Overview
Bytecode sizing ( Adds a Reviewed by Cursor Bugbot for commit 4eff7df. Bugbot is set up for automated code reviews on this repo. Configure here. |
The hardcoded -4 byte $pc correction assumed the inner copy-type load always emits 1 instruction. When the pointer entry's word offset exceeds 12 bits (data section >32KB), the inner load emits 3 instructions (MOVI+ADD+LW/LB), making the ADD $pc land 8 bytes further than the stored pointer value accounts for. Three fixes: - Dynamic $pc correction based on predicted pointer entry position - Pointer lookup keyed by (source DataId, instruction offset) instead of pointer value, preventing collisions when the same non-copy entry is loaded at multiple sites - Worst-case pointer word offset for size estimates, using non_configurables_size_in_bytes instead of total section size to avoid configurable entries inflating the threshold
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6888acd. Configure here.
The clippy::while_let_loop lint (now firing on stable) flags the
loop + let-else { break } pattern. Rewrite it as the equivalent
while-let loop.
|
@ironcev ready when you get a chance. This handles data-section offsets that don't fit a 12-bit |
Description
Closes #7612.
realize_load()panicked whenever a data section offset didn't fit the 12-bit immediate onLW/LB(4095 words, ~32KB). Any program whose data section grew past that limit hit an ICE during codegen.Copy-type loads now pick their encoding by offset size: a single
LW/LBwhen the offset fits 12 bits (unchanged), otherwiseMOVI+ADD $ds+LW/LB, with a clear panic once the offset can't fit the 18-bitMOVIimmediate (~256KB). Non-copy loads pre-insert their pointer into the data section in a separate pass keyed by load site, so the section stays immutable while bytecode is emitted and the inner pointer load can be one or three instructions. Size estimation inop_size_in_bytesandinstruction_size_not_far_jumpwas updated to count both forms, keeping jump offsets and the data-section offset aligned.The new layout shifts bytecode size and gas for a few programs, so the
dbg,vec, andconst_of_contract_callsnapshots were refreshed. Added alarge_data_sectionregression test that builds 4200+ distinctu64entries to exercise the wide-offset path.Checklist
Breaking*orNew Featurelabels where relevant.